using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

using UnityEngine;

public class THistory
{
	private LinkedList<TAction> _history;
	private LinkedListNode<TAction> root;
	private LinkedListNode<TAction> currentNode;
	
	
	
	public bool undoing = false;
	
	private static THistory instance;
 
	public static THistory Instance
	{
		get
		{
			if (instance == null)
			{
				instance = new THistory();
			}
 
			return instance;
		}
	}
	
	private THistory(){
		_history = new LinkedList<TAction>();
		
		root = new LinkedListNode<TAction>(null);
		_history.AddLast(root);
		
		currentNode = _history.Last;
	}
	
	public void addAction(TAction action){
		if(!isUndoing()){
			if(_history.Count ==  20){
				_history.RemoveFirst();
				_history.RemoveFirst();
				_history.AddFirst(root);
			}
			
			_history.AddLast(action);
			currentNode = _history.Last;
			
			StatsHandler.Instance.addMove();
		}
	}
	
	public void cancelLastAction(){
		_history.RemoveLast();
		currentNode = _history.Last;
	}
	
	public void loadState(TState state){
		
		undoing = true;
		clear();
		
		foreach(TAction action in state.Actions){
			_history.AddLast(action);	
		}
		
		redoToLast();
		
		clear();
	}
	
	public bool canUndo(){
		return currentNode != root;
	}
	
	public bool canRedo(){
		return currentNode.Next != null;
	}
	
	public void undo(){	
		currentNode.Value.undo();
		currentNode = currentNode.Previous;
		undoing = true;
	}
	
	public void redo(){
		currentNode = currentNode.Next;
		currentNode.Value.redo();
	}
	
	public void redoToLast(){
		while(canRedo()){
			redo();	
		}
	}
	
	public void exitUndoing(){
		//reset ();
		deleteFollowingActions();
		undoing = false;
	}
	
	public bool isUndoing(){
		return undoing;
	}
	
	public void clear(){
		_history.Clear();
		root = new LinkedListNode<TAction>(null);
		_history.AddLast(root);
		currentNode = _history.Last;
	}
	
	private void deleteFollowingActions(){
		while(currentNode != _history.Last){
			_history.RemoveLast();	
		}
	}
	
	private void reset(){
		instance = new THistory();
	}
	
	
 
}

